package com.woniuxy.system.controller;

import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.woniuxy.system.common.Result;
import com.woniuxy.system.model.vo.TokenRequest;
import com.woniuxy.system.model.vo.TokenResponse;
import com.woniuxy.system.util.TokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/token")
@Slf4j
public class TokenController {

    @Value("${jwt.signature}")
    private String signature;
    @Value("${jwt.accessTime}")
    private Long accessTime;

    /**
     * 通过长令牌置换短令牌
     * @return
     */
    @PostMapping("/refresh")
    public ResponseEntity refreshToken(@RequestBody TokenRequest tokenRequest, HttpServletRequest request){
        // 获取长令牌, 长令牌为空返回403
        String refreshToken = tokenRequest.getRefreshToken();
        if (!StringUtils.hasLength(refreshToken)) {
            // 设置响应状态码是403
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        // 校验长令牌: 校验失败，返回403
        boolean verify = JWTUtil.verify(refreshToken, signature.getBytes());
        if (!verify) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }

        // 校验长令牌是否过期,过期返回403
        JWT jwt = JWTUtil.parseToken(refreshToken);
        String exp = (String) jwt.getPayload("exp");
        LocalDateTime expTime = LocalDateTime.parse(exp, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        // 判断令牌的过期时间是否超过当前时间，如果超过：令牌过期
        if (expTime.isBefore(LocalDateTime.now())){
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }

        // 获取长令牌中的登录用户id
        Number number = (Number) jwt.getPayload("managerId");
        // 调用工具类，置换短令牌：生成短令牌
        String accessToken = TokenUtils.createToken(number.longValue(), signature, accessTime, TimeUnit.MINUTES, request);
        log.info("token置换，返回短令牌：", accessToken);
        // 返回短令牌
        return ResponseEntity.ok(new TokenResponse(accessToken));
    }
}
